---
title: Import / Export ReactJS
description: "Reusing existing React components"
canonical: "/docs/react/import-export-reactjs"
section: "Main Concepts"
order: 12
---

# Import / Export ReactJS

Reusing existing React components in ReScript is straightforward.
This guide will walk you through the steps required to import and use React components within ReScript,
including defining component props and handling various import scenarios.

## Basic Example

To reuse a React component in ReScript, create a new module, specify the component's location, and define its props.

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
module Confetti = {
  @module("react-confetti") @react.component
  external make: (~width: int, ~height: int) => React.element = "default"
}

// Assuming we are in App.res
@react.component
let make = () => {
  <Confetti width={300} height={300} />
}
```

```js
import ReactConfetti from "react-confetti";
import * as JsxRuntime from "react/jsx-runtime";

var Confetti = {};

function Playground(props) {
  return JsxRuntime.jsx(ReactConfetti, {
    width: 300,
    height: 300,
  });
}
```

</CodeTab>

## Importing from Relative Paths

You can import components from relative file paths using the `@module` attribute.  
Use "default" to indicate the default export, or specify a named export if needed.

### Named Export Example

<CodeTab labels={["ReScript"]}>

```res example
// Equivalent of import { Foo } from "bar"
module Foo = {
  @module("bar") @react.component
  external make: unit => React.element = "Foo"
}
```

</CodeTab>

## Defining Props Types

You can define a separate type for your component's props within the module.

### Props Type Example

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
module Confetti = {
  type confettiProps = {
    width: int,
    height: int,
  }

  @module("react-confetti") @react.component(: confettiProps)
  external make: confettiProps => React.element = "default"
}

@react.component
let make = () => {
  <Confetti width={300} height={300} />
}
```

```js
import ReactConfetti from "react-confetti";
import * as JsxRuntime from "react/jsx-runtime";

var Confetti = {};

function Playground(props) {
  return JsxRuntime.jsx(ReactConfetti, {
    width: 300,
    height: 300,
  });
}
```

</CodeTab>

## Optional Props

To define optional props, use the `?` symbol.

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
module Confetti = {
  type confettiProps = {
    width: int,
    height: int,
    initialVelocityX?: int,
    initialVelocityY?: int,
  }

  @module("react-confetti") @react.component(: confettiProps)
  external make: confettiProps => React.element = "default"
}

@react.component
let make = () => {
  <Confetti width={300} height={300} />
}
```

```js
import ReactConfetti from "react-confetti";
import * as JsxRuntime from "react/jsx-runtime";

var Confetti = {};

function Playground(props) {
  return JsxRuntime.jsx(ReactConfetti, {
    width: 300,
    height: 300,
  });
}
```

</CodeTab>

## Extending Built-in DOM Nodes

To accept existing DOM props for a component, extend the `JsxDOM.domProps` type.

<CodeTab labels={["ReScript", "JS Output"]}>

```res example
module Foo = {
  type fooProps = {
    ...JsxDOM.domProps,
    customProp: string,
  }

  @module("foo") @react.component(: fooProps)
  external make: fooProps => React.element = "default"
}

@react.component
let make = () => {
  <Foo width={"300px"} height={"300px"} customProp="bar" />
}
```

```js
import Foo from "foo";
import * as JsxRuntime from "react/jsx-runtime";

var Foo$1 = {};

function Playground(props) {
  return JsxRuntime.jsx(Foo, {
    height: "300px",
    width: "300px",
    customProp: "bar",
  });
}
```

</CodeTab>

In this example `width` and `height` can be set because `JsxDOM.domProps` was spread into `fooProps`.
